using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Linq;
using Pavilion;
using Pavilion.GameTools;

namespace Pavilion.Locks
{
    public enum Task
    {
        Complete,
        HalfComplete,
        CursorAlligned,
        CurosrNotAlligned,
        IfNotLocked
    }

    public class AnimationLock : ILock
    {
        public Task Task { get; set; }

        public AnimationLock()
        {
            this.Task = Task.Complete;
        }

        public AnimationLock(Task task, Animation animation)
        {
            this.Task = task;
        }

        public void Deserialize(XElement lockElement, string resourceName)
        {
            this.Task = (Task)Enum.Parse(typeof(Task), lockElement.Attribute("Task").Value);
        }

        public XElement Serialize()
        {
            XElement lockElement = new XElement("Lock");

            lockElement.Add(new XAttribute("Task", Task));

            return lockElement;
        }

        public LockMonitorBase CreateLockMonitor(GameItem gameItem)
        {
            return new AnimationLockMonitor(this);
        }

        public override string ToString()
        {
            return this.GetType().Name;
        }

        private class AnimationLockMonitor : LockMonitorBase
        {
            private AnimationLock animationLock;
            private Action<Animation> methodHandler;
            private TargetTool target;
            private PhysicalTypeTool physicalType;
            private AnimationTool animationTool;

            public AnimationLockMonitor(AnimationLock animationLock)
            {
                this.animationLock = animationLock;

                methodHandler = new Action<Animation>(AnimationPlayer_Complete);
            }

            public override void Dispose()
            {
                Deactivate();

                animationLock = null;
                target = null;
                animationTool = null;
                physicalType = null;
            }

            public override void Load(GameItem gameItem)
            {
                this.target = gameItem.ObtainTool<TargetTool>();
                this.animationTool = gameItem.ObtainTool<AnimationTool>();
                this.physicalType = gameItem.ObtainTool<PhysicalTypeTool>();

                Activate();
            }

            public override string ToString()
            {
                return this.GetType().Name;
            }

            private void Activate()
            {
                if (Task.Complete == animationLock.Task)
                    animationTool.Complete += methodHandler;
                else if (Task.IfNotLocked == animationLock.Task)
                    throw new Exception("The operation is not implemented.");
                else if (Task.CurosrNotAlligned == animationLock.Task)
                    throw new Exception("The operation is not implemented.");
                else if (Task.CursorAlligned == animationLock.Task)
                    throw new Exception("The operation is not implemented.");
                else if (Task.HalfComplete == animationLock.Task)
                    throw new Exception("The operation is not implemented.");
            }

            private void Deactivate()
            {
                if (Task.Complete == animationLock.Task)
                    animationTool.Complete -= methodHandler;
                else if (Task.IfNotLocked == animationLock.Task)
                    throw new Exception("The operation is not implemented.");
                else if (Task.CurosrNotAlligned == animationLock.Task)
                    throw new Exception("The operation is not implemented.");
                else if (Task.CursorAlligned == animationLock.Task)
                    throw new Exception("The operation is not implemented.");
                else if (Task.HalfComplete == animationLock.Task)
                    throw new Exception("The operation is not implemented.");
            }

            private void AnimationPlayer_Complete(Animation animation)
            {
                IsOpen = true;
                IsOpen = false;
            }
        }
    }
}
